/**
 * 
 */
package org.codesketch.controller.domain;

import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;

import org.codesketch.birch.common.Instance;
import org.codesketch.birch.ssh.File;
import org.codesketch.birch.ssh.ShellStatement;
import org.codesketch.controller.common.Preconditions;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Transient;
import org.springframework.data.mongodb.core.mapping.Document;

/**
 * @author Quirno Brizi
 *
 */
@Document
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Test {

	@Id
	@XmlTransient
	private String uuid;
	private Integer duration;
	private Status status;
	private Application application;
	private Environment environment;
	@Transient
	@XmlTransient
	private Set<File> resources;
	@Transient
	private Long startTime;
	
	/**
	 * 
	 */
	public Test() {
	}
	/**
	 * 
	 * @param application
	 * @param environment
	 */
	public Test(Application application, Environment environment) {
		this.application = application;
		this.environment = environment;
	}
	
	/**
	 * @return the uuid
	 */
	public String getUuid() {
		return uuid;
	}
	/**
	 * @param uuid the uuid to set
	 */
	public void setUuid(String uuid) {
		this.uuid = uuid;
	}
	/**
	 * @return the duration
	 */
	public Integer getDuration() {
		return duration;
	}
	/**
	 * @return the status
	 */
	public Status getStatus() {
		return status;
	}
	/**
	 * @param status the status to set
	 */
	public void setStatus(Status status) {
		this.status = status;
	}
	/**
	 * @return the application
	 */
	public Application getApplication() {
		return application;
	}
	/**
	 * Return the installation command for the application that should execute 
	 * the test.
	 * @return the install command as a {@link ShellStatement}
	 */
	public ShellStatement getInstall() {
		// TODO check for target directory
		return ShellStatement.with(application.getInstall());
	}
	/**
	 * Returns the running command for the application that should execute the 
	 * test.
	 * @return the run command as a {@link ShellStatement}
	 */
	public ShellStatement getRun() {
		// TODO check for target directory
		return ShellStatement.with(application.getRun());
	}
	/**
	 * @return the environment
	 */
	public Environment getEnvironment() {
		return environment;
	}
	/**
	 * @return the resources
	 */
	public Set<File> getResources() {
		if(Preconditions.checkNull(resources)) {
			resources = new HashSet<File>();
		}
		return Collections.unmodifiableSet(resources);
	}
	/**
	 * Return an unmodifiable list that enumerates the instances 
	 * started on AWS
	 * @return an unmodifiable {@link List} of {@link Instance}
	 */
	public List<Instance> getInstances() {
		return Collections.unmodifiableList(environment.getInstances());
	}
	/**
	 * @param resources the resources to set
	 */
	public void setResource(File resource) {
		if(Preconditions.checkNull(this.resources)) {
			this.resources = new HashSet<File>();
		}
		this.resources.add(resource);
	}
	/**
	 * @return the startTime
	 */
	public Long getStartTime() {
		return startTime;
	}
	/**
	 * @param startTime the startTime to set
	 */
	public void setStartTime(Long startTime) {
		this.startTime = startTime;
	}
	
	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object arg0) {
		if(arg0 instanceof Test) {
			Test param = (Test) arg0;
			return uuid.equals(param.uuid);
		} else {
			return false;
		}
	}
}
